﻿/*
 * Jonathan
 * Created by: Jonathan Montiverdi
 * Date: 8/6/2012
 * License: http://jonathan.codeplex.com/license
 */
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

using Awesomium.Core;
using Jonathan.Data;
using Jonathan.DataAccess.Sqlite;
using Monti.Docking;
using Monti.MVVM.Services;

namespace Jonathan.Logic
{
   /// <summary>
   /// View logic and data for a definition view.
   /// </summary>
   public class DefinitionViewModel : DockItem, IDataViewerModel
   {
      #region Fields
      
      private IMain m_Main;
      private string m_Html;
      private string m_Redirect;
      private IOptions m_Options;
      
      /// <summary>
      /// Event used to notify the item is closing.
      /// </summary>
      public event EventHandler ItemClosing;
      
      /// <summary>
      /// Event used to execute an html change request.
      /// </summary>
      public event HtmlChangeEventHandler HtmlChangeRequested;
      
      #endregion
      
      #region Setup
      
      /// <summary>
      /// Initializes a new defifinition view model.
      /// </summary>
      /// <param name="word">Word to initialize to, empty or null if none.</param>
      public DefinitionViewModel (string word = "")
      {
         this.Title = "Definitions";
         this.Definitions = new ObservableCollection <Definition> ();
         if (!string.IsNullOrEmpty (word))
         {
            this.ReadDefinition (word);
         }
      }
      
      #endregion
      
      #region Properties
      
      /// <summary>
      /// Gets or Sets the current definition.
      /// </summary>
      public ObservableCollection <Definition> Definitions { get; set; }
      
      /// <summary>
      /// Gets the main application.
      /// </summary>
      [SqliteIgnore]
      public IMain Main { get { return this.m_Main ?? (this.m_Main = ServiceManager.Resolve <IMain> ()); } }
      
      /// <summary>
      /// Gets the options of the application.
      /// </summary>
      [SqliteIgnore]
      public IOptions Options { get { return this.m_Options ?? (this.m_Options = ServiceManager.Resolve <IOptions> ()); } }
      
      /// <summary>
      /// Gets or Sets the html to display in the data viewer.
      /// </summary>
      [SqliteIgnore]
      public string Html
      {
         get { return this.m_Html; }
         set
         {
            if (this.m_Html != value)
            {
               this.m_Html = value;
               if (this.HtmlChangeRequested != null)
                  this.HtmlChangeRequested (new HtmlChangeEventArgs { TagId = "Html", Content = value });
               this.RaisePropertyChanged ("Html");
            }
         }
      }
      
      #endregion
      
      #region Methods
      
      /// <summary>
      /// Gets the list of a global javascript callbacks if any.
      /// </summary>
      public IDictionary <string, JSCallback> GetCallbacks ()
      {
         return null;
      }
      
      /// <summary>
      /// Reads the definition of the given word.
      /// </summary>
      /// <param name="word"></param>
      private void ReadDefinition (string word)
      {
         this.Definitions.Clear ();
         this.Title = word;
         this.ToolTip = "Definition for " + word;
         Sqlite.Read (Common.DEF_DB_PATH, this.Definitions, string.Format ("WHERE Name = '{0}'", word));
         var redirect = this.Definitions.FirstOrDefault (d => d.Content.Contains ("REDIRECT"));
         if (redirect == null)
            this.BuildHtml ();
         else
         {
            this.m_Redirect = string.Format ("<div class=\"alert\" style=\"width:100%\"><i class=\"icon-retweet\"></i> Redirected from {0}</div>", word);
            var split = redirect.Content.Split ('\"');
            this.ReadDefinition (split [1]);
         }
      }
      
      /// <summary>
      /// Builds the current html.
      /// </summary>
      private void BuildHtml ()
      {
         if (this.Definitions.Count <= 0) return;
         
         var html = new StringBuilder ();
         html.AppendLine ("<html>");
         html.AppendLine (Common.GetHtmlHead ("Definition"));
         html.AppendLine ("<body style=\"margin:0 10px;\">");
         foreach (var def in this.Definitions)
         {
            html.AppendLine (string.Format ("<div class=\"alert alert-info\" style=\"width=100%; font-size:2em;\"><strong>{0}</strong></div>", def.Word));
            if (!string.IsNullOrEmpty (this.m_Redirect))
               html.AppendLine (this.m_Redirect);
            html.AppendLine (string.Format ("<blockquote style=\"margin-top:10px;\">{0}</blockquote>", def.Content));
         }
         html.AppendLine ("</body>");
         html.AppendLine ("</html>");
         this.Html = html.ToString ();
      }
      
      /// <summary>
      /// Opens the given link.
      /// </summary>
      /// <param name="linkToOpen">Link to data to open.</param>
      public void Open (string linkToOpen)
      {
         
      }
      
      /// <summary>
      /// Occurs when the tab is closing.
      /// </summary>
      /// <returns>True if ok to close, otherwise false.</returns>
      public override bool Closing ()
      {
         if (this.ItemClosing != null)
            this.ItemClosing (this, EventArgs.Empty);
         return true;
      }
      
      #endregion
   }
}
